package com.nimlib;


import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;

import androidx.databinding.DataBindingUtil;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jinlejia.erp.R;
import com.jinlejia.erp.databinding.FragmentNimImBinding;
import com.jinlejia.erp.utils.SharePTool;
import com.lab.kit.StringKit;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.Observer;
import com.netease.nimlib.sdk.RequestCallback;
import com.netease.nimlib.sdk.RequestCallbackWrapper;
import com.netease.nimlib.sdk.msg.MsgServiceObserve;
import com.netease.nimlib.sdk.msg.model.CustomNotification;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import com.netease.nimlib.sdk.msg.model.MessageReceipt;
import com.netease.nimlib.sdk.msg.model.RecentContact;
import com.nimlib.adapter.IMMsgListAdapter;
import com.nimlib.uikit.TFragment;
import com.nimlib.utils.NimIMUtils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


public class NimIMFragment extends TFragment implements SwipeRefreshLayout.OnRefreshListener {


    public NimIMFragment() {
    }


    private FragmentNimImBinding binding;

    private IMMsgListAdapter adapter;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        binding = DataBindingUtil.inflate(inflater,R.layout.fragment_nim_im,container,false);
        binding.swipeRefreshLayout.setOnRefreshListener(this);
        binding.loadingLabel.setVisibility(View.VISIBLE);
        binding.messageLayout.setVisibility(View.GONE);
        loginIM();
        initSearch();
        return binding.getRoot();
    }


    private void initSearch(){
        binding.searchActionLayout.setOnClickListener(v-> {
            binding.searchActionLayout.setVisibility(View.GONE);
            binding.searchLayout.setVisibility(View.VISIBLE);
            binding.searchEditText.clearFocus();
            binding.searchEditText.requestFocus();
            InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.showSoftInput(binding.searchEditText, 0);
        });
        binding.searchEditText.setOnEditorActionListener((v, actionId, event) -> {
            if (actionId == EditorInfo.IME_ACTION_SEARCH){
                InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(binding.searchEditText.getWindowToken(), 0);
                queryList();
            }
            return false;
        });
        binding.searchCancelText.setOnClickListener (v->{
            binding.searchActionLayout.setVisibility(View.VISIBLE);
            binding.searchLayout.setVisibility(View.GONE);
            binding.searchEditText.clearFocus();
            binding.searchEditText.requestFocus();
            InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(binding.searchEditText.getWindowToken(), 0);
            binding.searchEditText.setText(null);
            queryList();
        });
    }

    private boolean isResume = false;
    private boolean isLogin = false;
    @Override
    public void onResume() {
        super.onResume();
        if (isLogin && !TextUtils.isEmpty(myAccount)){
            queryList();
        }
        isResume = true;
    }

    @Override
    public void onStop() {
        super.onStop();
        isResume = false;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        registerObservers(false);
    }

    //region Command事件注册
    private Observer<CustomNotification> commandObserver = new Observer<CustomNotification>() {
        @Override
        public void onEvent(CustomNotification message) {
            showCommandMessage(message);
        }
    };

    protected void showCommandMessage(CustomNotification message) {
        if (!isResume) {
            return;
        }
        String content = message.getContent();
        try {
            JSONObject json = JSON.parseObject(content);
            int id = json.getIntValue("id");
            if (id == 1) {
                // 正在输入
                System.out.println("对方正在输入...");
            } else {
                System.out.println("command: " + content);
            }
        } catch (Exception ignored) {

        }
    }
    //endregion

    //region 消息接收观察者
    private Observer<List<IMMessage>> messageObserver = new Observer<List<IMMessage>>() {
        @Override
        public void onEvent(List<IMMessage> imMessages) {
            for (IMMessage message:imMessages) {
                RecentContact contact = NimIMUtils.queryRecentContact(message.getSessionId());
                updateItem(contact);
            }
        }
    };

    private void updateItem(RecentContact recentContact){
        if (!adapter.notifyItem(recentContact)){
            adapter.addItemAtFirst(recentContact);
        }
    }

    //endregion
    private Observer<List<MessageReceipt>> messageReceipt = new Observer<List<MessageReceipt>>() {
        @Override
        public void onEvent(List<MessageReceipt> messageReceipts) {
            for (MessageReceipt receipt:messageReceipts) {
                RecentContact receiptContact = NimIMUtils.queryRecentContact(receipt.getSessionId());
                updateItem(receiptContact);
            }
        }
    };

    private void registerObservers(boolean register) {
        NIMClient.toggleNotification(!register);
        MsgServiceObserve service = NIMClient.getService(MsgServiceObserve.class);
        service.observeCustomNotification(commandObserver, register);
        service.observeReceiveMessage(messageObserver, register);
        service.observeMessageReceipt(messageReceipt,register);
    }

    private String myAccount = null;
    private void loginIM(){
        SharePTool.UserInfoBean infoBean = SharePTool.getUserInfoBean(getContext());
        String pin = infoBean.getPin();
        RequestCallback<String> callback = new RequestCallback<String>() {
            @Override
            public void onSuccess(String param) {
                isLogin = true;
                myAccount = param;
                binding.loadingLabel.setVisibility(View.GONE);
                binding.messageLayout.setVisibility(View.VISIBLE);
                queryList();
                Bundle arguments = getArguments();
                if (arguments!=null ){
                    Serializable extra = arguments.getSerializable("message");
                    if (extra instanceof ArrayList){
                        ArrayList list = (ArrayList) extra;
                        if (list.size() == 1){ //如果只有一条数据,则跳转到单独会话页面
                            IMMessage message = (IMMessage) list.get(0);
                            NimChartP2PActivity.start(getContext(),message.getFromAccount());
                        }
                    }
                }
            }

            @Override
            public void onFailed(int code) {

            }

            @Override
            public void onException(Throwable exception) {

            }
        };
        NimIMUtils.login(getContext(),true,pin,callback);
    }

    private List<RecentContact> items;

    private List<RecentContact> searchItems;
    private void queryList(){
        String myAccount = this.myAccount;
        String keyWords = binding.searchEditText.getText().toString().trim();
        if (items==null){
            items = new ArrayList<>();
        }
        if (searchItems==null){
            searchItems = new ArrayList<>();
        }
        searchItems.clear();
        if (adapter==null)adapter=new IMMsgListAdapter(getContext(),myAccount,items);

        adapter.setItemClickListener((userInfo,contact) -> {
            NimIMUtils.clearUnreadCount(userInfo.getAccount()); //清空全读
            NimChartP2PActivity.start(getContext(),userInfo,contact);
        });


        binding.recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        binding.recyclerView.setAdapter(adapter);

        if (!StringKit.isEmpty(keyWords)){
            for (RecentContact r:items) {
                if (r.getFromNick().contains(keyWords)){
                    searchItems.add(r);
                }
            }
            List<RecentContact> searchList = new ArrayList<>();
            Collections.copy(searchList,searchItems);
            adapter.updateList(searchList);
            return;
        }

        NimIMUtils.queryRecentContacts(new RequestCallbackWrapper<List<RecentContact>>() {
            @Override
            public void onResult(int code, List<RecentContact> result, Throwable exception) {
                adapter.updateList(result);
                binding.swipeRefreshLayout.setRefreshing(false);
                registerObservers(true);
            }
        });
    }

    @Override
    public void onRefresh() {
        if (isLogin && !TextUtils.isEmpty(myAccount)){
            queryList();
        }
    }
}
